package es.us.idinfor.rmplugin.algorithm;

import com.rapidminer.tools.container.Tupel;

import Jama.Matrix;

public class GMatrix {
	public static Matrix getGStarMatrix(Matrix g, Matrix a) {
		double value = 0;
		int rows = g.getRowDimension();
		int columns = g.getColumnDimension();
		Matrix res = Matrix.identity(rows, columns);
		
		for(int i = 0; i < rows; i++) {
			for(int j = 0; j < columns; j++) {
				value = g.get(i, j) * a.get(i, 0);
				value += g.get(j, i) * a.get(j, 0);
				value /= a.get(i, 0) + a.get(j, 0);
				
				res.set(i, j, value);
			}
		}
		
		return res;
	}
	
	public static Tupel<Integer, Integer> getInterdependentFeatures(Matrix g, double threshold) {
		double aux = 0;
		double limit = threshold;
		int rows = g.getRowDimension();
		int columns = g.getColumnDimension();
		Tupel<Integer, Integer> res = null;
		
		for(int i = 0; i < (rows - 1); i++) {
			for(int j = (i + 1); j < columns; j++) {
				if(g.get(i, j) != -1.0) {
					aux = g.get(i, j);
					
					if(limit < aux) {
						limit = aux;
						res = new Tupel<Integer, Integer>(i, j);
					}
				}
			}
		}
		
		return res;
	}
	
	public static Matrix getDiscriminatedMatrix(Matrix m, Tupel<Integer, Integer> features) {
		int discriminatedIndex = getRemovableFeature(m, features.getFirst(), features.getSecond());
		int d = m.getRowDimension();
		Matrix res = new Matrix(d, d);
		
		for(int i = 0; i < d; i++) {
			for(int j = 0; j < d; j++) {
				if((i != discriminatedIndex) && (j != discriminatedIndex)) {
					res.set(i, j, m.get(i, j));
				}
				else {
					res.set(i, j, -1.0);
				}
			}
		}
		
		return res;
	}
	
	private static int getRemovableFeature(Matrix m, int i, int j) {
		int res = j;
		
		if(getExclusiveValues(m, i) < getExclusiveValues(m, j)) {
			res = i;
		}
		
		return res;
	}
	
	private static double getExclusiveValues(Matrix m, int index) {
		double res = 0;
		int d = m.getRowDimension();
		
		for(int k = 0; k < d; k++) {
			if(k != index) {
				if(m.get(k, index) != -1.0) {
					res += m.get(k, index) + m.get(index, k);
				}
			}
		}
		
		return res;
	}
}
